package com.jfreer.mybatis.expand.javamapper;

import com.jfreer.mybatis.expand.javamapper.elements.*;
import org.mybatis.generator.api.CommentGenerator;
import org.mybatis.generator.api.dom.java.CompilationUnit;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.codegen.mybatis3.javamapper.JavaMapperGenerator;
import org.mybatis.generator.codegen.mybatis3.javamapper.elements.AbstractJavaMapperMethodGenerator;
import org.mybatis.generator.codegen.mybatis3.javamapper.elements.SelectAllMethodGenerator;
import org.mybatis.generator.config.PropertyRegistry;

import java.util.ArrayList;
import java.util.List;

import static org.mybatis.generator.internal.util.StringUtility.stringHasValue;
import static org.mybatis.generator.internal.util.messages.Messages.getString;

/**
 * User: landy
 * Date: 14-6-23
 * Time: 上午8:58
 */
public class FreeworkJavaMapperGenerator extends JavaMapperGenerator {
    @Override
    public List<CompilationUnit> getCompilationUnits() {
        progressCallback.startTask(getString("Progress.17", //$NON-NLS-1$
                introspectedTable.getFullyQualifiedTable().toString()));
        CommentGenerator commentGenerator = context.getCommentGenerator();

        FullyQualifiedJavaType type = new FullyQualifiedJavaType(
                introspectedTable.getMyBatis3JavaMapperType());
        Interface interfaze = new Interface(type);
        interfaze.setVisibility(JavaVisibility.PUBLIC);
        commentGenerator.addJavaFileComment(interfaze);

        String rootInterface = introspectedTable
                .getTableConfigurationProperty(PropertyRegistry.ANY_ROOT_INTERFACE);
        if (!stringHasValue(rootInterface)) {
            rootInterface = context.getJavaClientGeneratorConfiguration()
                    .getProperty(PropertyRegistry.ANY_ROOT_INTERFACE);
        }

        if (stringHasValue(rootInterface)) {
            FullyQualifiedJavaType fqjt = new FullyQualifiedJavaType(
                    rootInterface);
            interfaze.addSuperInterface(fqjt);
            interfaze.addImportedType(fqjt);
        }

        addCountByExampleMethod(interfaze);
        addDeleteByExampleMethod(interfaze);
        addDeleteByPrimaryKeyMethod(interfaze);
        addInsertMethod(interfaze);
        addInsertSelectiveMethod(interfaze);
        addSelectByExampleWithBLOBsMethod(interfaze);
        addSelectByExampleWithoutBLOBsMethod(interfaze);
        addSelectByPrimaryKeyMethod(interfaze);
        addUpdateByExampleSelectiveMethod(interfaze);
        addUpdateByExampleWithBLOBsMethod(interfaze);
        addUpdateByExampleWithoutBLOBsMethod(interfaze);
        addUpdateByPrimaryKeySelectiveMethod(interfaze);
        addUpdateByPrimaryKeyWithBLOBsMethod(interfaze);
        addUpdateByPrimaryKeyWithoutBLOBsMethod(interfaze);

        //2014-06-23 landy 增加额外的方法
        addCountAllMethod(interfaze);
        addDeleteAllMethod(interfaze);
        addSelectAllMethod(interfaze);
        //2014-06-28 landy 增加额外的方法
        addDeleteBySelectiveMethod(interfaze);
        addSelectBySelectiveMethod(interfaze);
        addInsertInBatchMethod(interfaze);
        addDeleteInBatchMethod(interfaze);

        List<CompilationUnit> answer = new ArrayList<CompilationUnit>();
        if (context.getPlugins().clientGenerated(interfaze, null,
                introspectedTable)) {
            answer.add(interfaze);
        }

        List<CompilationUnit> extraCompilationUnits = getExtraCompilationUnits();
        if (extraCompilationUnits != null) {
            answer.addAll(extraCompilationUnits);
        }

        return answer;
    }

    private void addDeleteInBatchMethod(Interface interfaze) {
        AbstractJavaMapperMethodGenerator methodGenerator = new DeleteInBatchMethodGenerator();
        initializeAndExecuteGenerator(methodGenerator, interfaze);
    }

    private void addInsertInBatchMethod(Interface interfaze) {
        AbstractJavaMapperMethodGenerator methodGenerator = new InsertInBatchMethodGenerator();
        initializeAndExecuteGenerator(methodGenerator, interfaze);
    }

    private void addSelectBySelectiveMethod(Interface interfaze) {
        AbstractJavaMapperMethodGenerator methodGenerator = new SelectBySelectiveMethodGenerator();
        initializeAndExecuteGenerator(methodGenerator, interfaze);
    }

    private void addDeleteBySelectiveMethod(Interface interfaze) {
        AbstractJavaMapperMethodGenerator methodGenerator = new DeleteBySelectiveMethodGenerator();
        initializeAndExecuteGenerator(methodGenerator, interfaze);
    }

    private void addSelectAllMethod(Interface interfaze) {
        AbstractJavaMapperMethodGenerator methodGenerator = new SelectAllMethodGenerator();
        initializeAndExecuteGenerator(methodGenerator, interfaze);
    }

    private void addDeleteAllMethod(Interface interfaze) {
        AbstractJavaMapperMethodGenerator methodGenerator = new DeleteAllMethodGenerator();
        initializeAndExecuteGenerator(methodGenerator, interfaze);
    }

    private void addCountAllMethod(Interface interfaze) {
        AbstractJavaMapperMethodGenerator methodGenerator = new CountAllMethodGenerator();
        initializeAndExecuteGenerator(methodGenerator, interfaze);
    }
}
